package com.brother.template.config;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author xjw
 * @date 2018/5/9
 */
public class ThreadManager {

    //锁对象
    private static final Object lockObj = new Object();
    private static volatile Map<String,ThreadPoolExecutor> threadPoolMap = new HashMap<>();

    /**
     * 根据 threadPoolName 获取一个线程池
     * @param threadPoolName 线程池的名称
     * @param corPoolSize
     * @param maximumPoolSize 最大线程数
     * @return
     */
    public static ThreadPoolExecutor getThreadPoolProxy(final String threadPoolName,final Integer corPoolSize,final Integer maximumPoolSize){
        ThreadPoolExecutor tpp = threadPoolMap.get(threadPoolName);
        if(tpp == null){
            synchronized (lockObj){
                tpp = threadPoolMap.get(threadPoolName);
                if(tpp == null){
                  tpp = new ThreadPoolExecutor(corPoolSize,maximumPoolSize,60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>(), new DefaultThreadFactory(threadPoolName));
                    threadPoolMap.put(threadPoolName,tpp);
                }
            }
        }
        return tpp;
    }

    /**
     *  获取一个名字为 System 的线程池。此线程池，用于执行系统任务
     * @return
     */
    public static ThreadPoolExecutor getSystemThreadPool(){
        return  ThreadManager.getThreadPoolProxy("System",0,200);
    }


    static class DefaultThreadFactory implements ThreadFactory {
//        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory(String name) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                    name +
                    "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon()){
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY){
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
}
